package ar.com.algotres.tpdos.modelo.fisica;

import java.util.LinkedList;
import java.util.List;

import ar.com.algotres.tpdos.modelo.fisica.direcciones.Direccion;
import ar.com.algotres.tpdos.modelo.fisica.disposiciones.Orientacion;

public class RepresentacionFisica {

	private List<BloqueNave> bloques;
	private Orientacion orientacion;

	public RepresentacionFisica(Orientacion orientacion, Posicion casillero,
			int cantidadDeBloques) throws CoordenadasDePosicioInvalidaException {
		this.bloques = orientacion.crearBloques(casillero, cantidadDeBloques);
		this.orientacion = orientacion;
	}

	private BloqueNave buscarBloqueDuplicado() {
		BloqueNave repetido = null;
		Integer dosVeces = 0;
		for (BloqueNave bloqueNave : this.bloques) {
			for (BloqueNave bloque : this.bloques) {
				if (bloqueNave.equals(bloque)) {
					dosVeces++;
					if (dosVeces == 2) {
						repetido = bloqueNave;
					}
				}
				dosVeces = 0;
			}
		}
		return repetido;
	}

	public boolean destruidaPorCompleto() {
		boolean hundido = true;
		for (BloqueNave bloqueNave : this.bloques) {
			if (!bloqueNave.estasAveriado()) {
				hundido = false;
			}
		}
		return hundido;
	}

	public Boolean estasAveriada() {
		for (BloqueNave bloque : this.bloques) {
			if (bloque.estasAveriado())
				return true;
		}
		return false;
	}

	public void explosionEn(Posicion posicion) {
		for (BloqueNave bloque : this.bloques) {
			bloque.explosionEn(posicion);
		}
	}

	public List<BloqueNave> getBloques() {
		return this.bloques;
	}

	public boolean hayBloqueEn(Posicion posicion) {
		Boolean hayBloque = false;
		for (BloqueNave bloque : this.bloques) {
			if (bloque.estasEn(posicion)) {
				hayBloque = true;
			}
		}
		return hayBloque;
	}

	public void invertir() throws CoordenadasDePosicioInvalidaException {
		this.orientacion.invertir();
		LinkedList<BloqueNave> bloquesAux;
		Direccion direccion = this.orientacion.direccion();
		BloqueNave inicial = this.buscarBloqueDuplicado();
		bloquesAux = (LinkedList<BloqueNave>) this.bloques;
		inicial = inicial != null ? inicial : bloquesAux.getLast();
		bloquesAux = new LinkedList<>();
		Posicion posicionInicial = inicial.getPosicion();
		for (BloqueNave bloque : this.bloques) {
			bloquesAux.add(new BloqueNave(posicionInicial, bloque.getEstado(),
					bloque.getOrden()));
			posicionInicial = direccion.damePosicionSiguiente(posicionInicial);
		}
		this.bloques = bloquesAux;
		bloquesAux = null;
	}

	public void modificarPosicionBloque(BloqueNave bloque,
			Posicion posicionSiguiente) {
		this.bloques.remove(bloque);
		this.bloques.add(new BloqueNave(posicionSiguiente, bloque.getEstado(),
				bloque.getOrden()));
	}

	@Override
	public String toString() {
		return "bloques=" + this.bloques.toString() + "]";
	}
}
